package fr.inserm.umr915.vcfserver.j2ee;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import fr.inserm.umr915.vcfserver.bio.ReferenceSequence;
import fr.inserm.umr915.vcfserver.bio.Segment;
import fr.inserm.umr915.vcfserver.bio.segparser.SegmentParser;

public class ReferenceServlet extends HttpServlet
	{
	private static final long serialVersionUID = 1L;
	
	
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
		{
		doGet(req,resp);
		}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
		{
		WebApplicationContext factory = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
		
		String pos=req.getParameter("segment");
		if(pos==null) pos=req.getParameter("loc");
		if(pos==null) pos=req.getParameter("pos");
		if(pos==null)
			{
			throw new ServletException("@segment is missing");
			}
		Segment segment=SegmentParser.parseOne(pos);
		
		
		ReferenceSequence refseq=(ReferenceSequence)factory.getBean("genome.reference");
		if(refseq==null) throw new ServletException("No reference for build 'genome.reference'");
		if(req.getServletPath().endsWith(".xml"))
			{
			resp.setContentType("text/xml");
			resp.setHeader("Content-Disposition","inline; filename="+segment.toString()+".xml;");
			OutputStream out= resp.getOutputStream();
			String encoding=resp.getCharacterEncoding();
			if(encoding==null)
				{
				encoding="UTF-8";
				resp.setCharacterEncoding(encoding);
				}
			try
				{
				XMLOutputFactory xmlfactory= XMLOutputFactory.newInstance();
				XMLStreamWriter w= xmlfactory.createXMLStreamWriter(out,encoding);
				w.writeStartDocument(encoding,"1.0");
				w.writeDTD("<!DOCTYPE DASDNA SYSTEM \"http://www.biodas.org/dtd/dasdna.dtd\">");
				w.writeStartElement("DASDNA");
				w.writeStartElement("SEQUENCE");
				w.writeAttribute("id", segment.getChromosome());
				w.writeAttribute("start", String.valueOf(segment.getChromStart()+1));
				w.writeAttribute("end", String.valueOf(segment.getChromEnd()));
				w.writeAttribute("version", "1.0");
				w.writeStartElement("DNA");
				w.writeAttribute("length", String.valueOf(segment.getChromEnd()-segment.getChromStart()));
				w.writeCharacters(new String(refseq.getSequence(segment)));
				w.writeEndElement();
				w.writeEndElement();
				w.writeEndElement();
				w.writeEndDocument();
				w.flush();
				w.close();
				out.flush();
				out.close();
				}
			catch(XMLStreamException err)
				{
				throw new IOException(err);
				}

			}
		else if(req.getServletPath().endsWith(".fa"))
			{
			String build= (String)factory.getBean("genome.build");
			resp.setContentType("text/plain");
			resp.setHeader("Content-Disposition","inline; filename="+segment.getChromosome()+"_"+segment.getChromStart()+"-"+segment.getChromEnd()+".fa;");
			PrintWriter out= resp.getWriter();
			out.print(">"+build+"|"+segment.getChromosome()+":"+segment.getChromStart()+"-"+segment.getChromEnd());
			String seq=new String(refseq.getSequence(segment));
			int i=0;
			while(i<seq.length())
				{
				out.println();
				int len=Math.min(60,seq.length()-i);
				out.write(seq, i, len);
				i+=len;
				}
			out.println();
			out.flush();
			out.close();
			}
		else
			{
			resp.setContentType("text/plain");
			resp.setHeader("Content-Disposition","inline; filename="+segment.getChromosome()+"_"+segment.getChromStart()+"-"+segment.getChromEnd()+".txt;");
			OutputStream out= resp.getOutputStream();
			out.write(refseq.getSequence(segment));
			out.flush();
			out.close();
			}
		}
	}
